﻿using CodeGenerator.Common;
using CodeGenerator.Core;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace CodeGenerator.UI
{
    public partial class FrmCreateMybatisMulti : Form
    {
        public FrmCreateMybatisMulti()
        {
            InitializeComponent();
        
        }

        private List<TableInfo> selectTable = null;

        private string entityNmae = string.Empty;
        private string dao = string.Empty;
        private string mapping = string.Empty;
        private string iService = string.Empty;
        private string service = string.Empty;
        private string outputDir = string.Empty;
        private string prefix = string.Empty;

        private BackgroundWorker doWork = null;

        private void FrmCreateCodeMulti_Load(object sender, EventArgs e)
        {
            progressBar1.Visible = false;
            MainSetting info = Config.GetSetupInfo();

            txtEntityName.Text = info.EntityPackage;
            txtDao.Text = info.DaoPackage;
            txtMapping.Text = info.Mapping;
            txtIservice.Text = info.IServicePackage;
            txtService.Text = info.ServicePackage;

            txtPrefix.Text = info.Prefix;
            txtOutputDir.Text = info.OutputDir;
        }

        private void btnChoose_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
            folderBrowserDialog.ShowDialog();
            txtOutputDir.Text = folderBrowserDialog.SelectedPath;
        }

        private void FrmCreateEntityMulti_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (doWork != null && doWork.IsBusy)
            {
                Common.MessageUtil.ShowWarning("任务执行中，无法关闭！！！");
                e.Cancel = true;
            }
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        } 

        private void btnOk_Click(object sender, EventArgs e)
        {
            selectTable = ucSelectTable1.GetSelectTable;

            if (selectTable.Count > 0)
            {
                outputDir = txtOutputDir.Text.Trim();

                if (string.IsNullOrEmpty(outputDir))
                {
                    Common.MessageUtil.ShowWarning("请选择输出路径！！！");
                    return;
                }

                entityNmae = txtEntityName.Text.Trim();
                dao = txtDao.Text.Trim();
                mapping = txtMapping.Text.Trim();
                iService = txtIservice.Text.Trim();
                service = txtService.Text.Trim();
                prefix = txtPrefix.Text.Trim();

                progressBar1.Visible = true;
                progressBar1.Minimum = 0;
                progressBar1.Maximum = selectTable.Count*7;
                doWork = new BackgroundWorker();
                doWork.DoWork += doWork_DoWork;
                doWork.ProgressChanged += doWork_ProgressChanged;
                doWork.RunWorkerCompleted += doWork_RunWorkerCompleted;
                doWork.WorkerReportsProgress = true;//此属性必须设置，否则读取不到进度
                doWork.WorkerSupportsCancellation = true; // 运行取消操作
                doWork.RunWorkerAsync();
            }
            else
            {
                Common.MessageUtil.ShowWarning("请至少选择一个表！！！");
            }
        }

        void doWork_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            //如果用户取消了当前操作就关闭窗口。
            if (e.Cancelled)
            {
                this.lblMsg.Text = "用户取消操作！！！";
            }
            else
            {
                this.lblMsg.Text = "执行完成！！！";
                doWork.CancelAsync();
                this.Close();
            }

        }

        void doWork_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            //修改进度条的显示。
            this.progressBar1.Value = e.ProgressPercentage;

            string message = e.UserState.ToString();
            this.lblMsg.Text = message;
        }

        void doWork_DoWork(object sender, DoWorkEventArgs e)
        {
            //在操作的过程中需要检查用户是否取消了当前的操作。
            if (doWork.CancellationPending == true)
            {
                e.Cancel = true;
                return;
            }

            BackgroundWorker bgWorker = sender as BackgroundWorker;

            ServerInfo serverInfo = Constant.CurrentServerInfo;
            serverInfo.DatabaseName = Constant.DatabaseName;
            IDatabase database = DBFactory.Database(serverInfo.DBType);

            string entityTempletePath = "\\Template\\Mybatis\\Entity.cshtml";
            string daoTempletePath = "\\Template\\Mybatis\\Dao.cshtml";
            string mapperTempletePath = "\\Template\\Mybatis\\Mapper.cshtml";
            string iServiceTempletePath = "\\Template\\Mybatis\\IService.cshtml";
            string serviceTempletePath = "\\Template\\Mybatis\\Service.cshtml";

            int i = 0;
            string dirPath = outputDir + "\\Mybatis\\";
            foreach (var table in selectTable)
            {
                bgWorker.ReportProgress(i++, "正在生成生成【" + table.Name + "】表代码...");

                #region 生成Mybatis代码模型
                MybatisCodeCreate model = new MybatisCodeCreate();

                // 表信息
                TableInfo tableInfo = new TableInfo();
                tableInfo.Name = table.Name;
                tableInfo.Comments = database.GetTableComments(serverInfo, Constant.DatabaseName, tableInfo.Name);
                tableInfo.ColumnList = database.GetColumnInfoList(serverInfo, serverInfo.DatabaseName, tableInfo.Name);

                model.TableInfo = tableInfo;

                // 基础配置信息
                model.Name = tableInfo.FilterName(prefix);  // 过滤掉前缀的表名
                model.EntityPackage = entityNmae;
                model.Mapping = mapping;
                model.DaoPackage = dao;
                model.IServicePackage = iService;
                model.ServicePackage = service;
                #endregion

                #region 生成代码
                bgWorker.ReportProgress(i++, "正在生成【" + table.Name + "】表实体类");
                string entityContent = RazorHelper.RunCompile(entityTempletePath, model);

                bgWorker.ReportProgress(i++, "正在生成【" + table.Name + "】表Dao类");
                string daoContent = RazorHelper.RunCompile(daoTempletePath, model);

                bgWorker.ReportProgress(i++, "正在生成【" + table.Name + "】表mapper文件");
                string mappingContent = RazorHelper.RunCompile(mapperTempletePath, model);

                bgWorker.ReportProgress(i++, "正在生成【" + table.Name + "】表Service接口类");
                string iServiceContent = RazorHelper.RunCompile(iServiceTempletePath, model);

                bgWorker.ReportProgress(i++, "正在生成【" + table.Name + "】表Service具体实现类");
                string serviceContent = RazorHelper.RunCompile(serviceTempletePath, model);
                #endregion

                #region 创建代码文件
                bgWorker.ReportProgress(i++, "正在保存表【" + table.Name + "】代码");

               // string dirPath = outputDir + "\\Mybatis\\" + model.Name + "\\";

                List<string> list = new List<string>();
                list.Add(dirPath);
                list.AddRange(model.EntityPackage.Split('.'));
                list.Add(Utils.Pascal(model.Name) + ".java");
                string entityPath = Path.Combine(list.ToArray());

                list.Clear();
                list.Add(dirPath);
                list.AddRange(model.DaoPackage.Split('.'));
                list.Add(Utils.Pascal(model.Name) + "Dao.java");
                string daoPath = Path.Combine(list.ToArray());


                list.Clear();
                list.Add(dirPath);
                list.AddRange(model.Mapping.Split('.'));
                list.Add(Utils.Pascal(model.Name) + "Mapping.java");
                string mapperPath = Path.Combine(list.ToArray());

                list.Clear();
                list.Add(dirPath);
                list.AddRange(model.IServicePackage.Split('.'));
                list.Add(Utils.Pascal(model.Name) + "Service.java");
                string iServicePath = Path.Combine(list.ToArray());

                list.Clear();
                list.Add(dirPath);
                list.AddRange(model.ServicePackage.Split('.'));
                list.Add(Utils.Pascal(model.Name) + "ServiceImpl.java");
                string serviceDirPath = Path.Combine(list.ToArray());

                DirectoryUtil.Write(entityPath, entityContent);
                DirectoryUtil.Write(daoPath, daoContent);
                DirectoryUtil.Write(mapperPath, mappingContent);
                DirectoryUtil.Write(iServicePath, iServiceContent);
                DirectoryUtil.Write(serviceDirPath, serviceContent);

                #endregion
            }
            System.Diagnostics.Process.Start(dirPath);
        }
    }
}
